home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-20
/
rs0422.zip
/
CONFIGUR
/
HEARD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-26
|
13KB
|
471 lines
/*
* Copyright 1988 by the Radio Amateur Telecommunications Society
* and Thomas A. Moulton, W2VY
*
* This software may only be modified, copied, distributed or
* executed for non-profit purposes by individuals operating
* systems in the Amateur Radio Service. Credit to the
* author(s) and to the Radio Amateur Telecommunications Society
* must be made in modules where RATS provided software is used,
* and in any announcements and documentation.
*
* As a non-profit, research and development organization, the
* Radio Amateur Telecommunications Society distributes software
* in both executable and source forms. This policy is in place
* to encourage the development and distribution of OSI-based,
* networking tools. In order to protect the interests of the
* Society and the authors, we have placed some conditions
* of use on the software. Other groups are encouraged
* to place the same or similar guidelines on
* software they produce.
*
* The Radio Amateur Telecommunications Society reserves the right
* to specify and alter the terms under which software provided by
* the Society may be used. This policy is consistent with the
* objective of uniform and consistent "Open Systems Interconnections."
*
* All acceptable Amateur Radio related uses of this software
* will be outlined in the "ROSE Implementer's Guide". Individuals
* or organizations wishing to add to, or modify the provisions of
* the guide to accommodate local or evolutionary requirements
* should document the proposed change(s) and forward them to the
* Society. If accepted, written notification will be provided by
* the Society to the submitting organization or individual(s).
* The Society will then issue a "ROSE Implementer's Guide Change
* Notice". Periodically, the Society will re-issue the "ROSE
* Implementer's Guide" and incorporate the text of the change
* notices. This procedure has been put in to place to ensure
* compatibility between systems and to ensure their "Openness"
* and interoperability.
*
* No part of this software may be used in other packages
* without prior authorization from the author or the Society.
* Software incorporating this module, all or in part, must be
* provided to the Society prior to distribution or use by
* anyone not directly involved in testing of the revised
* environment. Current releases of the combined software must
* be provided to the Society in both source and executable
* forms. Adequate documention to produce an executable module
* from the provided source must also be included.
*
* Non-Amateur Radio non-profit uses may be authorized on a case
* by case basis. Inquiries for such use may be made in writing
* to the Society. Non-commercial uses consistent with the
* general principles of Open Systems Interconnection Reference
* Model will be generally considered with favor.
*
* Commercial licensing of the software is also available based
* on normal commercial terms. Licensing inquiries should be
* directed to the Society. Commercial licensing of the standard
* software will be done in situations which materially benefit
* the Amateur Radio Packet Network. Additional licensing is
* reserved by the individual authors.
*
* The Radio Amateur Telecommunications Society provides this software
* on an "as is" basis. The Society assumes no liability for
* loss incurred through the use of this software. Amateur Radio
* use of this software implies non-commercial and voluntary
* development, deployment and use of this software in a "Amateur",
* non-commercial service. Commercial users are encouraged to
* inspect their copies of the source code. Source code modification
* licenses are available if a combined Object and Source Code
* license was not originally established.
*
* The Society may be contacted by writing or calling at:
*
* The Radio Amateur Telecommunications Society
* 206 North Vivyen Street.
* Bergenfield, New Jersey 07621
*
* Telephone: 201-387-8896
*
*/
#include "data.h"
#include "buffer.h"
#include "iface.h"
#include "timer.h"
#include "ax25.h"
#include "ax25l2.h"
#include "l3struc.h"
#include "x25cause.h"
#include "l3calls.h"
#include "tx.h"
#include "config.h"
#include "upfcn.h"
int NULLFCN(), clr_heard(), con_heard(), recv_boot();
int send_heard(), rst_boot(), init_heard(), unload_heard();
struct upfcn heard={
{{0x90, 0x8a, 0x82, 0xa4, 0x88, 0x40}, {0x00}}, /* HEARD-0 */
rst_boot, clr_heard, con_heard, recv_boot,
send_heard, init_heard, unload_heard,
"HEARD - ROSE Switch Heard List, Version 1.1\r"
};
struct VCS *heard_llcn;
struct datastr *mkpkt(), *bappstr();
struct datastr *heard_in;
struct tmrblk *heard_timer;
void siosnd();
struct datastr *ax25l2(), *heardit();
int NULLFCN();
struct datastr *NULLPKT();
int callcmp();
extern unsigned char digi;
extern struct axcb *links;
extern struct interface *ifaces[4];
extern struct interface port0, port1;
extern unsigned char node_addr[16];
struct interface Port0 = {0, "Port 0", siosnd, heardit, NULLPKT, NULLFCN, NULLFCN };
struct interface Port1 = {1, "Port 1", siosnd, heardit, NULLPKT, NULLFCN, NULLFCN };
char *ftype_name[] = { " "," I "," RR "," RNR "," REJ "," UI ",
" DISC "," UA "," FRMR "," DM "," SABM " };
struct mhlist {
unsigned int age; /* How long ago we "first" heard this entry */
unsigned int last; /* How long ago we last heard this entry */
int port; /* Port they were heard on */
unsigned int rxc; /* How many frames have been heard */
char *ftype; /* Frame type of last frame */
struct ax25_addr call[7];
};
#define LISTSIZE 32
struct mhlist heard_list[LISTSIZE];
zap_it(mhl)
register struct mhlist *mhl;
{
static int i,j;
mhl->age =
mhl->last =
mhl->port =
mhl->rxc = 0;
mhl->ftype = ftype_name[0];
for (i=0;i<7;i++) {
for (j=0;j<ALEN;j++) mhl->call[i].call[j] = 0;
mhl->call[i].ssid = 0;
}
}
int
heard_tick()
{
static int i, j;
register struct mhlist *mhl;
queue(&heard_timer, heard_tick, 5, 0);
mhl = &heard_list[0];
for (i=0;i<LISTSIZE;i++) /* Make each entry get older */ {
if (mhl->call[0].call[0] == 0) break;
mhl->age++;
mhl->last++;
mhl++;
}
}
#if 0
if (mhl->rxc < 10 && mhl->age > 900) { units on age changes
for (j=i;j<19;j++) {
bmove(mhl+1, mhl, sizeof(struct mhlist));
}
} else mhl++;
}
while (mhl < &heard_list[20]) zap_it(mhl++);
}
#endif
int
init_heard()
{
static int i;
static struct axcb *axcb;
register struct mhlist *mhl;
mhl = heard_list;
for (i=0;i<LISTSIZE;i++) zap_it(mhl++);
queue(&heard_timer, heard_tick, 5, 0);
heard_llcn = NULL;
axcb = links;
while (axcb) /* Fix all iface's of all links */ {
if (axcb->iface == ifaces[0]) axcb->iface = &Port0;
if (axcb->iface == ifaces[1]) axcb->iface = &Port1;
axcb=axcb->next;
}
ifaces[0] = &Port0;
ifaces[1] = &Port1;
}
int
unload_heard()
{
static struct VCS *vc;
register struct axcb *axcb;
ifaces[0] = &port0;
ifaces[1] = &port1;
kill(heard_timer);
while (heard_llcn) /* Clear all active calls */ {
vc = heard_llcn;
heard_llcn = vc->next;
set_p(vc, P6, DTE_Orig+122);
}
axcb = links;
while (axcb) /* Restore any links to the correct interface */ {
if (axcb->iface == &Port0) axcb->iface = &port0;
if (axcb->iface == &Port1) axcb->iface = &port1;
axcb = axcb->next;
}
return 1;
}
int
con_heard(vc)
register struct VCS *vc;
{
vc->next = heard_llcn; /* This works even when _llcn is NULL */
heard_llcn = vc;
vc=vc->peer;
if (!vc) return;
(*vc->SEND)(vc,info_pkt());
}
int
clr_heard(vc,c)
struct VCS *vc;
int c;
{
register struct VCS *vcp;
if (heard_llcn == vc) heard_llcn = vc->next; /* First item */
else {
vcp = heard_llcn;
while (vcp->next && vcp->next != vc) vcp = vcp->next;
if (vcp->next == vc) vcp->next = vc->next;
}
vc->next = NULL;
set_p(vc, P1, 0);
}
int
send_heard(vc, pkt)
struct VCS *vc;
struct datastr *pkt;
{
static int i;
vc_queue_data(vc,pkt);
i = 15; /* Default to One Screen Full */
if (vc->tx_queue) /* There is stuff waiting */ {
while ((heard_in = vc->tx_queue)) {
vc->tx_queue = heard_in->next;
if (bgetch(&heard_in) == '*') i = LISTSIZE; /* ALL */
free_buffer(heard_in);
}
heard_stns(vc->peer, i);
}
return 256; /* We are never busy! */
}
int
find_guy(mh)
struct ax25_addr mh[7];
{
static int i, j, c;
for (i=0;i<7;i++) /* Check each address */ {
for (j=0;j<ALEN;j++) {
c = mh[i].call[j] & 0x0ff;
if (c != 0 && c < 0x40) return -2;
}
}
for (i=0;i<LISTSIZE;i++) /* See if we have heard this guy before */ {
for (j=0;j<7;j++) /* Still have a match? */ {
if (!callcmp(&mh[j], &heard_list[i].call[j])) break;
if (j == 6) return i; /* All Matches! */
}
}
return -1;
}
struct datastr *
heardit(iface, pkt)
struct interface *iface;
struct datastr *pkt;
{
static struct datastr *bp;
static int i, j, k, l, xmtr;
static struct ax25_addr mh[7];
int get_addr();
bp = dup_pkt(pkt);
for (i=0;i<7;i++) /* Init calls */ {
for (j=0;j<ALEN;j++) mh[i].call[j] = 0;
mh[i].ssid = 0;
}
if ((xmtr=get_addr(bp, mh, TRUE)) > 1) /* Had valid addresses */ {
if (xmtr > 2) /* Have digipeaters */ {
if (digi > 2) {
xmtr = digi;
} else if (digi) xmtr=0;
}
i = find_guy(mh);
if (i != -2) {
j = k = 0;
if (i == -1) i = LISTSIZE-1;
else {
j = heard_list[i].age;
k = heard_list[i].rxc;
}
if (i) for (l=i;l>0;l--) {
bmove(&heard_list[l-1],&heard_list[l], sizeof(struct mhlist));
}
heard_list[0].port = iface->dev;
heard_list[0].age = j;
heard_list[0].last = 0;
heard_list[0].rxc = k+1;
for (i=0;i<7;i++) {
mh[i].ssid &= SSID;
callcpy(&heard_list[0].call[i], &mh[i]);
}
/* digi points to the NEXT digi, not the XMTR! */
if (xmtr>2) heard_list[0].call[xmtr-1].ssid |= REPEATED;
if (bp) heard_list[0].ftype =
ftype_name[decode_ctl(*bp->rdata)+1];
}
}
free_pkt(bp);
return (ax25l2(iface, pkt));
}
putdec(bp, val, w)
struct datastr *bp;
unsigned int val;
int w;
{
static char z[10];
static unsigned int v, u10;
static int i;
u10 = 10;
for (i=0;i<10;i++) z[i]=' ';
z[9]=0;
v=val;
for (i=8;i>=0, v!=0;i--) /* Stuff one digit at a time */ {
z[i] = '0' + (v - (v/u10)*u10);
v = v / 10;
}
bappstr(bp, &z[9-w]);
}
put_hhm(bp, val)
struct datastr *bp;
unsigned int val;
{
static char z[9];
static unsigned int v, i;
for (i=0;i<9;i++) z[i]='0';
z[2]=':';
z[5]=z[8]=0;
v = val/12; /* Convert to Mins */
i = v/60;
if (i>0) /* Number of hours */ {
z[0] = (i/10) + '0';
z[1] = (i - ((i/10) * 10)) +'0';
}
i = v - (i*60);
if (i>0) {
z[3] = (i/10) + '0';
z[4] = (i - ((i/10) * 10)) +'0';
}
bappstr(bp,z);
}
int call_strx(stn, str)
unsigned char *stn, *str;
{
static int i;
int call_str();
i = call_str(stn, str);
if (str[i-1] == '0' && str[i-2] == '-') i -= 2;
return i;
}
heard_stns(vc, num)
struct VCS *vc;
int num;
{
static struct datastr *bp;
static int i, j;
static char str[80], *ch;
register struct mhlist *mhl;
int x121_str();
bp=mkpkt("Heard List for ");
ch = str;
ch += call_strx(&L3CALL[0], ch);
*ch++ = ' ';
*ch++ = ' ';
ch += x121_str(node_addr, ch);
*ch++ = 0x0d;
*ch = 0;
bappstr(bp, str);
bappstr(bp, " Last First (How long ago)\r");
bappstr(bp, "Port Station Destination Heard Heard RXCnt FType Path\r");
mhl = heard_list;
for (i=0;i<num;i++) /* For each item in the list */ {
if (mhl->call[0].call[0] == 0) break;
ch = str;
*ch++ = ' ';
*ch++ = ' ';
*ch++ = mhl->port+0x30;
*ch++ = ' ';
*ch++ = ' ';
j = call_strx(&mhl->call[1], ch);
ch += j;
while (j++ < 10) *ch++ = ' ';
j = call_strx(&mhl->call[0], ch);
ch += j;
while (j++ < 12) *ch++ = ' ';
*ch = 0;
bappstr(bp,str);
put_hhm(bp, mhl->last);
bappstr(bp, " ");
put_hhm(bp, mhl->age);
putdec(bp, mhl->rxc, 7);
bappstr(bp, mhl->ftype);
ch = str;
*ch = ' ';
*ch = ' ';
for (j=2;j<7;j++) /* Do the Path */ {
if (mhl->call[j].call[0] == 0) break;
ch++;
ch += call_strx(&mhl->call[j], ch);
if (mhl->call[j].ssid & REPEATED) *ch++ = '*';
*ch = ',';
}
*ch++ = 0x0d;
*ch = 0;
bappstr(bp, str);
mhl++;
}
bappstr(bp, "END>\r");
(*vc->SEND)(vc, bp);
}